package com.yunbao.ioc.utils;

import com.yunbao.ioc.annotation.*;
import com.yunbao.ioc.example.ExampleBeanPostProcessor;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.SQLOutput;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by louisyuu on 2020/3/3 下午5:55
 */
public class AnnotationUtils {

    /**
     * 校验注有Autowired注解属性对应的class，是否顶了@Service @Component @Repository注解
     *
     * @param allClasses
     */
    public static void validationAutowired(Collection<Class<?>> allClasses) {
        for (Class<?> cls : allClasses) {
            //获取类中的所有的方法
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                Autowired autowired = field.getAnnotation(Autowired.class);
                if (autowired != null) {
                    if (getBeanClass(cls) == null) {
                        throw new RuntimeException(cls.getName() + " must mark the @Component above the class");
                    }
                }
            }

        }

    }


    public static Set<Class<?>> getBeanClasses(List<Class<?>> classes) {
        Set<Class<?>> beanClasses = new HashSet<>();
        for (Class<?> cls : classes) {
            Class<?> beanClass = getBeanClass(cls);
            if (beanClass != null) {
                beanClasses.add(beanClass);
            }
        }
        return beanClasses;

    }


    public static Class<?> getBeanClass(Class<?> clazz) {

        if (clazz.getAnnotation(Service.class) != null
                || clazz.getAnnotation(Component.class) != null
                || clazz.getAnnotation(Repository.class) != null
                || clazz.isAnnotationPresent(Controller.class)
        ) {
            return clazz;
        }
        return null;
    }


    public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
        // Shortcut: directly present on the element, with no processing needed?
        if (element.isAnnotationPresent(annotationType)) {
            return true;
        }
        return false;
    }


    public static void main(String[] args) {
        System.out.println(ExampleBeanPostProcessor.class.getSuperclass());
    }

}
